using System;
using System.Text;
using System.Text.RegularExpressions;

namespace ExcelTemplateEngine.OpenXML
{
    /// <summary>
    /// 单元格地址辅助类
    /// </summary>
    public static class CellAddressHelper
    {
        private static readonly Regex AddressRegex = new Regex(@"^([A-Z]+)(\d+)$", RegexOptions.Compiled);
        private static readonly Regex RangeRegex = new Regex(@"^([A-Z]+\d+):([A-Z]+\d+)$", RegexOptions.Compiled);
        
        /// <summary>
        /// 列号转列名（1 -> A, 27 -> AA）
        /// </summary>
        /// <param name="column">列号（1-based）</param>
        /// <returns>列名</returns>
        public static string ColumnNumberToName(int column)
        {
            if (column < 1)
                throw new ArgumentException("列号必须大于0", nameof(column));
                
            var sb = new StringBuilder();
            while (column > 0)
            {
                column--;
                sb.Insert(0, (char)('A' + column % 26));
                column /= 26;
            }
            return sb.ToString();
        }
        
        /// <summary>
        /// 列名转列号（A -> 1, AA -> 27）
        /// </summary>
        /// <param name="columnName">列名</param>
        /// <returns>列号（1-based）</returns>
        public static int ColumnNameToNumber(string columnName)
        {
            if (string.IsNullOrEmpty(columnName))
                throw new ArgumentException("列名不能为空", nameof(columnName));
                
            int result = 0;
            for (int i = 0; i < columnName.Length; i++)
            {
                result = result * 26 + (columnName[i] - 'A' + 1);
            }
            return result;
        }
        
        /// <summary>
        /// 创建单元格地址
        /// </summary>
        /// <param name="row">行号（1-based）</param>
        /// <param name="column">列号（1-based）</param>
        /// <returns>单元格地址，如"A1"</returns>
        public static string CreateAddress(int row, int column)
        {
            if (row < 1)
                throw new ArgumentException("行号必须大于0", nameof(row));
            if (column < 1)
                throw new ArgumentException("列号必须大于0", nameof(column));
                
            return $"{ColumnNumberToName(column)}{row}";
        }
        
        /// <summary>
        /// 解析单元格地址
        /// </summary>
        /// <param name="address">单元格地址，如"A1"</param>
        /// <returns>行号和列号（1-based）</returns>
        public static (int row, int column) ParseAddress(string address)
        {
            if (string.IsNullOrEmpty(address))
                throw new ArgumentException("地址不能为空", nameof(address));
                
            var match = AddressRegex.Match(address.ToUpper());
            if (!match.Success)
                throw new ArgumentException($"无效的单元格地址: {address}", nameof(address));
                
            var columnName = match.Groups[1].Value;
            var rowString = match.Groups[2].Value;
            
            return (int.Parse(rowString), ColumnNameToNumber(columnName));
        }
        
        /// <summary>
        /// 解析范围地址
        /// </summary>
        /// <param name="range">范围地址，如"A1:B10"</param>
        /// <returns>起始单元格和结束单元格地址</returns>
        public static (string startCell, string endCell) ParseRange(string range)
        {
            if (string.IsNullOrEmpty(range))
                throw new ArgumentException("范围不能为空", nameof(range));
                
            var match = RangeRegex.Match(range.ToUpper());
            if (!match.Success)
                throw new ArgumentException($"无效的范围地址: {range}", nameof(range));
                
            return (match.Groups[1].Value, match.Groups[2].Value);
        }
        
        /// <summary>
        /// 偏移地址
        /// </summary>
        /// <param name="address">原始地址</param>
        /// <param name="rowOffset">行偏移量</param>
        /// <param name="columnOffset">列偏移量</param>
        /// <returns>偏移后的地址</returns>
        public static string OffsetAddress(string address, int rowOffset, int columnOffset)
        {
            var (row, column) = ParseAddress(address);
            return CreateAddress(row + rowOffset, column + columnOffset);
        }
        
        /// <summary>
        /// 检查地址是否有效
        /// </summary>
        /// <param name="address">单元格地址</param>
        /// <returns>是否有效</returns>
        public static bool IsValidAddress(string address)
        {
            if (string.IsNullOrEmpty(address))
                return false;
                
            return AddressRegex.IsMatch(address.ToUpper());
        }
        
        /// <summary>
        /// 检查范围是否有效
        /// </summary>
        /// <param name="range">范围地址</param>
        /// <returns>是否有效</returns>
        public static bool IsValidRange(string range)
        {
            if (string.IsNullOrEmpty(range))
                return false;
                
            return RangeRegex.IsMatch(range.ToUpper());
        }
    }
}